
Imports std

Namespace storclient
    Public Module storclient

        Public Const defaultRetryTimes As UInt64 = talkTime.client2room.retrytimes
        Public Const defaultHoldTime As Int64 = talkTime.client2room.holdtime
        Public Const defaultLiveTime As Int64 = talkTime.client2room.livetime

        Public Sub initialTalk(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime)
            If talk Is Nothing Then
                talk = New tcpTalk()
            Else
                talk.sendData.clear()
            End If
            talk.host = host
            talk.port = port
            talk.holdtime = holdtime
            talk.livetime = livetime
        End Sub

        Private Function checksuccess(ByVal t As tcpTalk) As Boolean
            assert(Not t Is Nothing)
            assert(t.receiveData().fieldCount() > 0)
            Return strsame(t.receiveData.take(Of String)(0), protocol.success, False)
        End Function

        Private Function talkhelper(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal holdtime As Int64, ByVal livetime As Int64, _
                                    ByVal _do As _do(Of tcpTalk, Boolean), _
                                    ByVal checksucc As Boolean, _
                                    ByVal command As String, _
                                    ByVal suppressError As Boolean) As returnValue
            initialTalk(talk, host, port, holdtime, livetime)
            assert(_do(talk))
            If talk.talk() Then
                If talk.receiveData().fieldCount() = 0 Then
                    raiseError("talk.receiveData().fieldCount() = 0, contains no response.", _
                               errorHandle.errorType.system)
                    Return returnValue.fail
                ElseIf checksucc Then
                    If checksuccess(talk) Then
                        Return returnValue.success
                    Else
                        If Not suppressError Then
                            raiseError("storserver " + talk.display() + " returns fail when " + command, _
                                       errorHandle.errorType.warning)
                        End If
                        Return returnValue.fail
                    End If
                Else
                    Return returnValue.success
                End If
            Else
                raiseError("cannot talk with stroserver " + displayHostPort(talk.host, talk.port), _
                           errorHandle.errorType.exclamation)
                Return returnValue.overtime
            End If
        End Function

        Private Function talkhelper(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal holdtime As Int64, ByVal livetime As Int64, _
                                    ByVal checksucc As Boolean, _
                                    ByVal command As String, _
                                    ByVal suppressError As Boolean, _
                                    ByVal ParamArray d() As String) As returnValue
            Dim _do As _do(Of tcpTalk, Boolean) = Function(ByRef t As tcpTalk) As Boolean
                                                      assert(t.sendData.insert(command))
                                                      If Not d Is Nothing AndAlso d.Length() > 0 Then
                                                          For i As Int64 = 0 To d.Length() - 1
                                                              assert(t.sendData().insert(d(i)))
                                                          Next
                                                      End If
                                                      Return True
                                                  End Function
            Return talkhelper(talk, host, port, holdtime, livetime, _do, checksucc, command, suppressError)
        End Function

        Private Function _try(ByRef talk As tcpTalk, ByVal _do As _do(Of tcpTalk, returnValue), _
                              ByVal retrytimes As Int64) As returnValue
            Dim _do2 As _do(Of tcpTalk, Object, Object, Object, returnValue) = _
                Function(ByRef t As tcpTalk, _
                         ByRef _N As Object, ByRef _N2 As Object, ByRef _N3 As Object) As returnValue
                    Return _do(t)
                End Function
            Return _try(talk, Nothing, Nothing, Nothing, _do2, retrytimes)
        End Function

        Private Function _try(Of T)(ByRef talk As tcpTalk, ByRef r As T, _
                                    ByVal _do As _do(Of tcpTalk, T, returnValue), _
                                    ByVal retrytimes As Int64) As returnValue
            Dim _do2 As _do(Of tcpTalk, T, Object, Object, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef r1 As T, ByRef _N As Object, ByRef _N2 As Object) As returnValue
                    Return _do(_t, r1)
                End Function
            Return _try(talk, r, Nothing, Nothing, _do2, retrytimes)
        End Function

        Private Function _try(Of T, T2)(ByRef talk As tcpTalk, ByRef r1 As T, ByRef r2 As T2, _
                                        ByVal _do As _do(Of tcpTalk, T, T2, returnValue), _
                                        ByVal retrytimes As Int64) As returnValue
            Dim _do2 As _do(Of tcpTalk, T, T2, Object, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _r1 As T, ByRef _r2 As T2, _
                         ByRef _N As Object) As returnValue
                    Return _do(_t, _r1, _r2)
                End Function
            Return _try(talk, r1, r2, Nothing, _do2, retrytimes)
        End Function

        Private Function _try(Of T, T2, T3)(ByRef talk As tcpTalk, ByRef r1 As T, ByRef r2 As T2, ByRef r3 As T3, _
                                            ByVal _do As _do(Of tcpTalk, T, T2, T3, returnValue), _
                                            ByVal retrytimes As Int64) As returnValue
            Dim rtn As returnValue = returnValue.overtime
            If retrytimes = 0 Then
                retrytimes = defaultRetryTimes
            End If
            While retrytimes > 0
                rtn = _do(talk, r1, r2, r3)
                If rtn = returnValue.overtime Then
                    retrytimes -= 1
                Else
                    Exit While
                End If
            End While

            Return rtn
        End Function

        'DEFAULT CONTAINER IS VECTOR
        'convert to set if need a unique key list
        Public Function list(ByRef talk As tcpTalk, ByVal host As String, _
                             ByVal port As Int32, ByRef l As [set](Of String), _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim s As vector(Of String) = Nothing
            Dim rtn As returnValue
            rtn = list(talk, host, port, s, holdtime, livetime)
            If Not s Is Nothing Then
                assert(vector2set(s, l), "cannot convert vector to set.")
            End If
            Return rtn
        End Function

        Public Function list(ByVal host As String, ByVal port As Int32, _
                             ByRef l As [set](Of String), _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return list(Nothing, host, port, l, holdtime, livetime)
        End Function

        Private Function readlist(ByVal talk As tcpTalk, ByRef l As vector(Of String)) As returnValue
            assert(Not talk Is Nothing)
            assert(talk.receiveData().fieldCount > 1)
            If l Is Nothing Then
                l = New vector(Of String)()
            Else
                l.clear()
            End If
            Dim count As UInt64
            Dim str As String = Nothing
            str = talk.receiveData.take(Of String)(1)
            If convertor.touint64(str, count) Then
                If talk.receiveData.fieldCount <> count + 2 Then
                    raiseError("talk.receiveData.fieldCount<>count+2.", errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim i As UInt64
                For i = 2 To count + 1
                    assert(l.push_back(talk.receiveData.take(Of String)(i)), "l.insert returns false.")
                Next

                Return returnValue.success
            Else
                raiseError("storserver returns no uint64 for keycount.", errorHandle.errorType.exclamation)
                Return returnValue.fail
            End If
        End Function

        Private Function listImpl(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByRef l As vector(Of String), _
                                  ByVal cmd As String, _
                                  ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, cmd, False)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                Return readlist(talk, l)
            End If
        End Function

        Public Function list(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                             ByRef l As vector(Of String), _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return listImpl(talk, host, port, l, protocol.storserver.list, holdtime, livetime)
        End Function

        Public Function list(ByVal host As String, ByVal port As Int32, ByRef l As vector(Of String), _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return list(Nothing, host, port, l, holdtime, livetime)
        End Function

        Public Function trylist(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByRef l As [set](Of String), _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim v As vector(Of String) = Nothing
            Dim rtn As returnValue
            rtn = trylist(talk, host, port, v, retrytimes, holdtime, livetime)
            If Not v Is Nothing Then
                assert(vector2set(v, l), "cannot convert vector to set.")
            End If
            Return rtn
        End Function

        Private Delegate Function _list(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                        ByRef l As vector(Of String), _
                                        ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue

        Private Function trylistImpl(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                     ByRef l As vector(Of String), _
                                     ByVal list As _list, _
                                     ByVal retrytimes As UInt64, _
                                     ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            Dim _do As _do(Of tcpTalk, vector(Of String), returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _l As vector(Of String)) As returnValue
                    Return list(_t, host, port, _l, holdtime, livetime)
                End Function
            Return _try(talk, l, _do, retrytimes)
        End Function

        Public Function trylist(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByRef l As vector(Of String), _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trylistImpl(talk, host, port, l, AddressOf list, retrytimes, holdtime, livetime)
        End Function

        Public Function trylist(ByVal host As String, ByVal port As Int32, ByRef l As [set](Of String), _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trylist(Nothing, host, port, l, retrytimes, holdtime, livetime)
        End Function

        Public Function trylist(ByVal host As String, ByVal port As Int32, ByRef l As vector(Of String), _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trylist(Nothing, host, port, l, retrytimes, holdtime, livetime)
        End Function

        Public Function status(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByRef allSlicesCount As UInt64, ByRef unhealthSlicesCount As UInt64, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.status, False)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If (talk.receiveData.fieldCount <> 3) Then
                    raiseError("talk.receiveData.fieldCount<>3 when status command returns success.", _
                               errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim str As String = Nothing
                str = talk.receiveData.take(Of String)(1)
                If Not convertor.touint64(str, allSlicesCount) Then
                    raiseError("storserver returns no uint64 for all_slices_count.", _
                               errorHandle.errorType.exclamation)
                    Return returnValue.fail
                End If
                str = talk.receiveData.take(Of String)(2)
                If Not convertor.touint64(str, unhealthSlicesCount) Then
                    raiseError("storserver returns no uint64 for unhealth_slices_count.", _
                               errorHandle.errorType.exclamation)
                    Return returnValue.fail
                End If

                Return returnValue.success
            End If
        End Function

        Public Function status(ByVal host As String, ByVal port As Int32, _
                               ByRef allSlicesCount As UInt64, ByRef unhealthSlicesCount As UInt64, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return status(Nothing, host, port, allSlicesCount, unhealthSlicesCount, holdtime, livetime)
        End Function

        Public Function trystatus(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByRef allSlicesCount As UInt64, ByRef unhealthSlicesCount As UInt64, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, UInt64, UInt64, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _a As UInt64, ByRef _u As UInt64) As returnValue
                    Return status(_t, host, port, _a, _u, holdtime, livetime)
                End Function
            Return _try(talk, allSlicesCount, unhealthSlicesCount, _do, retrytimes)
        End Function

        Public Function trystatus(ByVal host As String, ByVal port As Int32, _
                                  ByRef allSlicesCount As UInt64, ByRef unhealthSlicesCount As UInt64, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trystatus(Nothing, host, port, allSlicesCount, unhealthSlicesCount, retrytimes, holdtime, livetime)
        End Function

        Public Function capacity(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 ByRef cap As UInt64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.capacity, False)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If (talk.receiveData.fieldCount <> 2) Then
                    raiseError("talk.receiveData.fieldCount<>2 when capacity command returns success." _
                                , errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim str As String = Nothing
                str = talk.receiveData.take(Of String)(1)
                If Not convertor.touint64(str, cap) Then
                    raiseError("storserver returns no uint64 for capacity.", errorHandle.errorType.exclamation)
                    Return returnValue.fail
                Else
                    Return returnValue.success
                End If
            End If
        End Function

        Public Function capacity(ByVal host As String, ByVal port As Int32, ByRef cap As UInt64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return capacity(Nothing, host, port, cap, holdtime, livetime)
        End Function

        Public Function trycapacity(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByRef cap As UInt64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, UInt64, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _c As UInt64) As returnValue
                    Return capacity(_t, host, port, _c, holdtime, livetime)
                End Function
            Return _try(talk, cap, _do, retrytimes)
        End Function

        Public Function trycapacity(ByVal host As String, ByVal port As Int32, _
                                    ByRef cap As UInt64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trycapacity(Nothing, host, port, cap, retrytimes, holdtime, livetime)
        End Function

        Public Function valuesize(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByRef size As UInt64, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.valuesize, False)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If (talk.receiveData.fieldCount <> 2) Then
                    raiseError("talk.receiveData.fieldCount<>2 when size command returns success.", _
                               errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim str As String = Nothing
                str = talk.receiveData.take(Of String)(1)
                If Not convertor.touint64(str, size) Then
                    raiseError("storserver returns no uint64 for size.", errorHandle.errorType.exclamation)
                    Return returnValue.fail
                Else
                    Return returnValue.success
                End If
            End If
        End Function

        Public Function valuesize(ByVal host As String, ByVal port As Int32, ByRef size As UInt64, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return valuesize(Nothing, host, port, size, holdtime, livetime)
        End Function

        Public Function tryvaluesize(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                     ByRef size As UInt64, _
                                     Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                     Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                     Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, UInt64, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _s As UInt64) As returnValue
                    Return valuesize(_t, host, port, _s, holdtime, livetime)
                End Function
            Return _try(talk, size, _do, retrytimes)
        End Function

        Public Function tryvaluesize(ByVal host As String, ByVal port As Int32, _
                                     ByRef size As UInt64, _
                                     Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                     Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                     Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryvaluesize(Nothing, host, port, size, retrytimes, holdtime, livetime)
        End Function

        Public Function seek(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                             ByVal key As String, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.seek, True, key)
        End Function

        Public Function seek(ByVal host As String, ByVal port As Int32, ByVal key As String, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return seek(Nothing, host, port, key, holdtime, livetime)
        End Function

        Public Function tryseek(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByVal key As String, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return seek(_t, host, port, key, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryseek(ByVal host As String, ByVal port As Int32, ByVal key As String, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryseek(Nothing, host, port, key, retrytimes, holdtime, livetime)
        End Function

        Public Function read(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                             ByVal key As String, ByRef buff As bytes, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.read, True, key)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If (talk.receiveData.fieldCount <> 2) Then
                    raiseError("talk.receiveData.fieldCount<>2 when read command returns success." _
                                , errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                If talk.receiveData.take(1, buff) Then
                    Return returnValue.success
                Else
                    raiseError("talk.receiveData.take(1,buff) returns false.", errorHandle.errorType.exclamation)
                    Return returnValue.fail
                End If
            End If
        End Function

        Public Function read(ByVal host As String, ByVal port As Int32, _
                             ByVal key As String, ByRef buff As bytes, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return read(Nothing, host, port, key, buff, holdtime, livetime)
        End Function

        Public Function tryread(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByVal key As String, ByRef buff As bytes, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, bytes, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _b As bytes) As returnValue
                    Return read(_t, host, port, key, _b, holdtime, livetime)
                End Function
            Return _try(talk, buff, _do, retrytimes)
        End Function

        Public Function tryread(ByVal host As String, ByVal port As Int32, _
                                ByVal key As String, ByRef buff As bytes, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryread(Nothing, host, port, key, buff, retrytimes, holdtime, livetime)
        End Function

        Private Function wm(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                            ByVal key As String, ByVal buff As bytes, _
                            ByVal cmd As String, _
                            ByVal holdtime As Int64, ByVal livetime As Int64, _
                            ByVal suppressError As Boolean) As returnValue
            Dim _do As _do(Of tcpTalk, Boolean) = Function(ByRef t As tcpTalk) As Boolean
                                                      assert(t.sendData.insert(cmd))
                                                      assert(t.sendData.insert(key))
                                                      assert(t.sendData.insert(buff))
                                                      Return True
                                                  End Function
            Return talkhelper(talk, host, port, holdtime, livetime, _do, True, cmd, suppressError)
        End Function

        Public Function modify(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, ByVal buff As bytes, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return wm(talk, host, port, key, buff, protocol.storserver.modify, holdtime, livetime, False)
        End Function

        Public Function modify(ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, ByVal buff As bytes, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return modify(Nothing, host, port, key, buff, holdtime, livetime)
        End Function

        Private Delegate Function _wm(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                      ByVal key As String, ByVal buff As bytes, _
                                      ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue

        Private Function trywm(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByVal wm As _wm, _
                               ByVal key As String, ByVal buff As bytes, _
                               ByVal retrytimes As UInt64, _
                               ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            assert(Not wm Is Nothing)
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return wm(_t, host, port, key, buff, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function trymodify(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, ByVal buff As bytes, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trywm(talk, host, port, AddressOf modify, key, buff, retrytimes, holdtime, livetime)
        End Function

        Public Function trymodify(ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, ByVal buff As bytes, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trymodify(Nothing, host, port, key, buff, retrytimes, holdtime, livetime)
        End Function

        Public Function delete(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.delete, True, key)
        End Function

        Public Function delete(ByVal host As String, ByVal port As Int32, ByVal key As String, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return delete(Nothing, host, port, key, holdtime, livetime)
        End Function

        Public Function trydelete(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return delete(_t, host, port, key, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function trydelete(ByVal host As String, ByVal port As Int32, ByVal key As String, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trydelete(Nothing, host, port, key, retrytimes, holdtime, livetime)
        End Function

        Public Function write(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                              ByVal key As String, ByVal buff As bytes, _
                              Optional ByVal holdtime As Int64 = defaultHoldTime, _
                              Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return wm(talk, host, port, key, buff, protocol.storserver.write, holdtime, livetime, False)
        End Function

        Public Function write(ByVal host As String, ByVal port As Int32, _
                              ByVal key As String, ByVal buff As bytes, _
                              Optional ByVal holdtime As Int64 = defaultHoldTime, _
                              Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return write(Nothing, host, port, key, buff, holdtime, livetime)
        End Function

        Public Function trywrite(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByVal buff As bytes, _
                                 Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trywm(talk, host, port, AddressOf write, key, buff, retrytimes, holdtime, livetime)
        End Function

        Public Function trywrite(ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByVal buff As bytes, _
                                 Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trywrite(Nothing, host, port, key, buff, retrytimes, holdtime, livetime)
        End Function

        Public Function uniqueWrite(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByVal buff As bytes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return wm(talk, host, port, key, buff, protocol.storserver.uniqueWrite, holdtime, livetime, True)
        End Function

        Public Function uniqueWrite(ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByVal buff As bytes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return uniqueWrite(Nothing, host, port, key, buff, holdtime, livetime)
        End Function

        Public Function tryuniqueWrite(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                       ByVal key As String, ByVal buff As bytes, _
                                       Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                       Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                       Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trywm(talk, host, port, AddressOf uniqueWrite, key, buff, retrytimes, holdtime, livetime)
        End Function

        Public Function tryuniqueWrite(ByVal host As String, ByVal port As Int32, _
                                       ByVal key As String, ByVal buff As bytes, _
                                       Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                       Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                       Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim talk As tcpTalk = Nothing
            Return tryuniqueWrite(talk, host, port, key, buff, retrytimes, holdtime, livetime)
        End Function

        Public Function open(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.open, False)
        End Function

        Public Function open(ByVal host As String, ByVal port As Int32, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return open(Nothing, host, port, holdtime, livetime)
        End Function

        Public Function tryopen(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return open(_t, host, port, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryopen(ByVal host As String, ByVal port As Int32, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryopen(Nothing, host, port, retrytimes, holdtime, livetime)
        End Function

        Public Function close(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                              Optional ByVal holdtime As Int64 = defaultHoldTime, _
                              Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.close, False)
        End Function

        Public Function close(ByVal host As String, ByVal port As Int32, _
                              Optional ByVal holdtime As Int64 = defaultHoldTime, _
                              Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return close(Nothing, host, port, holdtime, livetime)
        End Function

        Public Function tryclose(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return close(_t, host, port, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryclose(ByVal host As String, ByVal port As Int32, _
                                 Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryclose(Nothing, host, port, retrytimes, holdtime, livetime)
        End Function

        Public Function full(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, False, protocol.storserver.full, True)
            Select Case rtn
                Case returnValue.fail
                    Return returnValue.success
                Case returnValue.overtime
                    Return returnValue.overtime
                Case returnValue.success
                    If checksuccess(talk) Then
                        Return returnValue.success
                    Else
                        Return returnValue.fail
                    End If
                Case Else
                    assert(False, "should cover all situations.")
                    Return returnValue.fail
            End Select
        End Function

        Public Function full(ByVal host As String, ByVal port As Int32, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return full(Nothing, host, port, holdtime, livetime)
        End Function

        Public Function tryfull(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return full(_t, host, port, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryfull(ByVal host As String, ByVal port As Int32, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryfull(Nothing, host, port, retrytimes, holdtime, livetime)
        End Function

        Public Function health(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.health, False)
        End Function

        Public Function health(ByVal host As String, ByVal port As Int32, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return health(Nothing, host, port, holdtime, livetime)
        End Function

        Public Function tryhealth(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return health(_t, host, port, holdtime, livetime)
                End Function
            Return _try(talk, _do, ifoper(Of UInt64)(retrytimes = 0, 1, retrytimes))
        End Function

        Public Function tryhealth(ByVal host As String, ByVal port As Int32, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryhealth(Nothing, host, port, retrytimes, holdtime, livetime)
        End Function

        Public Function retire(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.retire, False)
        End Function

        Public Function retire(ByVal host As String, ByVal port As Int32, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return retire(Nothing, host, port, holdtime, livetime)
        End Function

        Public Function tryretire(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return retire(_t, host, port, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryretire(ByVal host As String, ByVal port As Int32, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryretire(Nothing, host, port, retrytimes, holdtime, livetime)
        End Function

        Public Function empty(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                              Optional ByVal holdtime As Int64 = defaultHoldTime, _
                              Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.empty, True)
        End Function

        Public Function empty(ByVal host As String, ByVal port As Int32, _
                              Optional ByVal holdtime As Int64 = defaultHoldTime, _
                              Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return empty(Nothing, host, port, holdtime, livetime)
        End Function

        Public Function tryempty(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return empty(_t, host, port, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryempty(ByVal host As String, ByVal port As Int32, _
                                 Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryempty(Nothing, host, port, retrytimes, holdtime, livetime)
        End Function

        Private Function sizeofImpl(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByRef size As UInt64, _
                                    ByVal cmd As String, _
                                    ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, cmd, True, key)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If (talk.receiveData.fieldCount <> 2) Then
                    raiseError("talk.receiveData.fieldCount<>2 when " + cmd + " command returns success.", _
                               errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim str As String = Nothing
                str = talk.receiveData.take(Of String)(1)
                If Not convertor.touint64(str, size) Then
                    raiseError("storserver returns no uint64 for " + cmd + " " + key, _
                               errorHandle.errorType.exclamation)
                    Return returnValue.fail
                Else
                    Return returnValue.success
                End If
            End If
        End Function

        Public Function sizeof(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, ByRef size As UInt64, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return sizeofImpl(talk, host, port, key, size, protocol.storserver.sizeof, holdtime, livetime)
        End Function

        Public Function sizeof(ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, ByRef size As UInt64, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return sizeof(Nothing, host, port, key, size, holdtime, livetime)
        End Function

        Private Delegate Function _sizeof(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                          ByVal key As String, ByRef size As UInt64, _
                                          ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue

        Private Function trysizeofImpl(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                       ByVal key As String, ByRef size As UInt64, _
                                       ByVal sizeof As _sizeof, _
                                       ByVal retrytimes As UInt64, _
                                       ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            assert(Not sizeof Is Nothing)
            Dim _do As _do(Of tcpTalk, UInt64, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _s As UInt64) As returnValue
                    Return sizeof(_t, host, port, key, _s, holdtime, livetime)
                End Function
            Return _try(talk, size, _do, retrytimes)
        End Function

        Public Function trysizeof(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, ByRef size As UInt64, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trysizeofImpl(talk, host, port, key, size, AddressOf sizeof, retrytimes, holdtime, livetime)
        End Function

        Public Function tryesizeof(ByVal host As String, ByVal port As Int32, _
                                   ByVal key As String, ByRef size As UInt64, _
                                   Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trysizeof(Nothing, host, port, key, size, retrytimes, holdtime, livetime)
        End Function

        Private Function keycountImpl(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                      ByRef count As UInt64, _
                                      ByVal cmd As String, _
                                      ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, cmd, False)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If (talk.receiveData.fieldCount <> 2) Then
                    raiseError("talk.receiveData.fieldCount<>2 when " + cmd + " command returns success." _
                                , errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim str As String = Nothing
                str = talk.receiveData.take(Of String)(1)
                If Not convertor.touint64(str, count) Then
                    raiseError("storserver returns no uint64 for " + cmd, errorHandle.errorType.exclamation)
                    Return returnValue.fail
                Else
                    Return returnValue.success
                End If
            End If
        End Function

        Public Function keycount(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 ByRef count As UInt64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return keycountImpl(talk, host, port, count, protocol.storserver.keycount, holdtime, livetime)
        End Function

        Public Function keycount(ByVal host As String, ByVal port As Int32, _
                                 ByRef count As UInt64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return keycount(Nothing, host, port, count, holdtime, livetime)
        End Function

        Private Delegate Function _keycount(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                            ByRef count As UInt64, _
                                            ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue

        Private Function trykeycountImpl(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                         ByRef count As UInt64, _
                                         ByVal keycount As _keycount, _
                                         ByVal retrytimes As UInt64, _
                                         ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            Dim _do As _do(Of tcpTalk, UInt64, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _c As UInt64) As returnValue
                    Return keycount(_t, host, port, _c, holdtime, livetime)
                End Function
            Return _try(talk, count, _do, retrytimes)
        End Function

        Public Function trykeycount(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByRef count As UInt64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trykeycountImpl(talk, host, port, count, AddressOf keycount, retrytimes, holdtime, livetime)
        End Function

        Public Function trykeycount(ByVal host As String, ByVal port As Int32, _
                                    ByRef count As UInt64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trykeycount(Nothing, host, port, count, retrytimes, holdtime, livetime)
        End Function

        Public Function sync(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                             ByVal desthost As String, ByVal destport As Int32, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.sync, False, _
                              desthost, Convert.ToString(destport))
        End Function

        Public Function sync(ByVal host As String, ByVal port As Int32, _
                             ByVal desthost As String, ByVal destport As Int32, _
                             Optional ByVal holdtime As Int64 = defaultHoldTime, _
                             Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return sync(Nothing, host, port, desthost, destport, holdtime, livetime)
        End Function

        Public Function trysync(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByVal desthost As String, ByVal destport As Int32, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return sync(_t, host, port, desthost, destport, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function trysync(ByVal host As String, ByVal port As Int32, _
                                ByVal desthost As String, ByVal destport As Int32, _
                                Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trysync(Nothing, host, port, desthost, destport, retrytimes, holdtime, livetime)
        End Function

        Public Function version(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByRef ver As String, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, False, protocol.storserver.version, True)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                ver = talk.receiveData().take(Of String)(0)
                Return returnValue.success
            End If
        End Function

        Public Function version(ByVal host As String, ByVal port As Int32, _
                                ByRef ver As String, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return version(Nothing, host, port, ver, holdtime, livetime)
        End Function

        Public Function tryversion(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                   ByRef ver As String, _
                                   Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, String, returnValue) = _
                Function(ByRef _t As tcpTalk, ByRef _v As String) As returnValue
                    Return version(_t, host, port, _v, holdtime, livetime)
                End Function
            Return _try(talk, ver, _do, retrytimes)
        End Function

        Public Function tryversion(ByVal host As String, ByVal port As Int32, _
                                   ByRef ver As String, _
                                   Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryversion(Nothing, host, port, ver, retrytimes, holdtime, livetime)
        End Function

        Public Function tsRead(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, ByRef buff As bytes, ByRef ts As Int64, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim rtn As returnValue = Nothing
            rtn = talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.tsRead, True, key)
            If rtn <> returnValue.success Then
                Return rtn
            Else
                If talk.receiveData().fieldCount() <> 3 Then
                    raiseError("talk.receiveData.fieldCount <> 3 when tsRead command returns success.", _
                               errorHandle.errorType.system)
                    Return returnValue.fail
                End If

                Dim tbuff As bytes = Nothing
                If talk.receiveData().take(1, buff) AndAlso _
                   talk.receiveData().take(2, tbuff) AndAlso convertor.toint64(+tbuff, ts) Then
                    Return returnValue.success
                Else
                    raiseError("talk.receiveData.take(1, buff) or " + _
                               "talk.receiveData.take(2, tbuff) or convertor.toint64(+tbuff, ts) returns false.", _
                               errorHandle.errorType.exclamation)
                    Return returnValue.fail
                End If
            End If
        End Function

        Public Function tsRead(ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, ByRef buff As bytes, ByRef ts As Int64, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsRead(Nothing, host, port, key, buff, ts, holdtime, livetime)
        End Function

        Public Function tryTsRead(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, ByRef buff As bytes, ByRef ts As Int64, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, bytes, Int64, returnValue) = _
                Function(ByRef t As tcpTalk, ByRef b As bytes, ByRef _t As Int64) As returnValue
                    Return tsRead(t, host, port, key, b, _t, holdtime, livetime)
                End Function
            Return _try(talk, buff, ts, _do, retrytimes)
        End Function

        Public Function tryTsRead(ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, ByRef buff As bytes, ByRef ts As Int64, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsRead(Nothing, host, port, key, buff, ts, retrytimes, holdtime, livetime)
        End Function

        Public Function tsSeek(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.tsSeek, True, key)
        End Function

        Public Function tsSeek(ByVal host As String, ByVal port As Int32, _
                               ByVal key As String, _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsSeek(Nothing, host, port, key, holdtime, livetime)
        End Function

        Public Function tryTsSeek(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return tsSeek(_t, host, port, key, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryTsSeek(ByVal host As String, ByVal port As Int32, _
                                  ByVal key As String, _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsSeek(Nothing, host, port, key, retrytimes, holdtime, livetime)
        End Function

        Private Function tswm(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                              ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                              ByVal cmd As String, _
                              ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            Dim _do As _do(Of tcpTalk, Boolean) = Function(ByRef t As tcpTalk) As Boolean
                                                      assert(t.sendData.insert(cmd))
                                                      assert(t.sendData.insert(key))
                                                      assert(t.sendData.insert(buff))
                                                      assert(t.sendData.insert(convertor.tobytes(ts)))
                                                      Return True
                                                  End Function
            Return talkhelper(talk, host, port, holdtime, livetime, _do, True, cmd, False)
        End Function

        Public Function tsWrite(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tswm(talk, host, port, key, buff, ts, protocol.storserver.tsWrite, holdtime, livetime)
        End Function

        Public Function tsWrite(ByVal host As String, ByVal port As Int32, _
                                ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsWrite(Nothing, host, port, key, buff, ts, holdtime, livetime)
        End Function

        Private Delegate Function _tswm(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                        ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                        ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue

        Private Function trytswm(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                 ByVal tswm As _tswm, _
                                 ByVal retrytimes As UInt64, _
                                 ByVal holdtime As Int64, ByVal livetime As Int64) As returnValue
            assert(Not tswm Is Nothing)
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return tswm(_t, host, port, key, buff, ts, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryTsWrite(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                   ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                   Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trytswm(talk, host, port, key, buff, ts, AddressOf tsWrite, retrytimes, holdtime, livetime)
        End Function

        Public Function tryTsWrite(ByVal host As String, ByVal port As Int32, _
                                   ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                   Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsWrite(Nothing, host, port, key, buff, ts, retrytimes, holdtime, livetime)
        End Function

        Public Function tsModify(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tswm(talk, host, port, key, buff, ts, protocol.storserver.tsModify, holdtime, livetime)
        End Function

        Public Function tsModify(ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsModify(Nothing, host, port, key, buff, ts, holdtime, livetime)
        End Function

        Public Function tryTsModify(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trytswm(talk, host, port, key, buff, ts, AddressOf tsModify, retrytimes, holdtime, livetime)
        End Function

        Public Function tryTsModify(ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByVal buff As bytes, ByVal ts As Int64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsModify(Nothing, host, port, key, buff, ts, retrytimes, holdtime, livetime)
        End Function

        Public Function tsList(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                               ByRef l As vector(Of String), _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return listImpl(talk, host, port, l, protocol.storserver.tsList, holdtime, livetime)
        End Function

        Public Function tsList(ByVal host As String, ByVal port As Int32, _
                               ByRef l As vector(Of String), _
                               Optional ByVal holdtime As Int64 = defaultHoldTime, _
                               Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsList(Nothing, host, port, l, holdtime, livetime)
        End Function

        Public Function tryTsList(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                  ByRef l As vector(Of String), _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trylistImpl(talk, host, port, l, AddressOf tsList, retrytimes, holdtime, livetime)
        End Function

        Public Function tryTsList(ByVal host As String, ByVal port As Int32, _
                                  ByRef l As vector(Of String), _
                                  Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                  Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                  Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsList(Nothing, host, port, l, retrytimes, holdtime, livetime)
        End Function

        Public Function tsDelete(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                         ByVal key As String, _
                         Optional ByVal holdtime As Int64 = defaultHoldTime, _
                         Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return talkhelper(talk, host, port, holdtime, livetime, True, protocol.storserver.tsDelete, True, key)
        End Function

        Public Function tsDelete(ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsDelete(Nothing, host, port, key, holdtime, livetime)
        End Function

        Public Function tryTsDelete(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Dim _do As _do(Of tcpTalk, returnValue) = _
                Function(ByRef _t As tcpTalk) As returnValue
                    Return tsDelete(_t, host, port, key, holdtime, livetime)
                End Function
            Return _try(talk, _do, retrytimes)
        End Function

        Public Function tryTsDelete(ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsDelete(Nothing, host, port, key, retrytimes, holdtime, livetime)
        End Function

        Public Function tsSizeof(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByRef size As UInt64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return sizeofImpl(talk, host, port, key, size, protocol.storserver.tsSizeof, holdtime, livetime)
        End Function

        Public Function tsSizeof(ByVal host As String, ByVal port As Int32, _
                                 ByVal key As String, ByRef size As UInt64, _
                                 Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                 Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsSizeof(Nothing, host, port, key, size, holdtime, livetime)
        End Function

        Public Function tryTsSizeof(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByRef size As UInt64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trysizeofImpl(talk, host, port, key, size, AddressOf tsSizeof, retrytimes, holdtime, livetime)
        End Function

        Public Function tryTsSizeof(ByVal host As String, ByVal port As Int32, _
                                    ByVal key As String, ByRef size As UInt64, _
                                    Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                    Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                    Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsSizeof(Nothing, host, port, key, size, retrytimes, holdtime, livetime)
        End Function

        Public Function tsKeyCount(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                   ByRef count As UInt64, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return keycountImpl(talk, host, port, count, protocol.storserver.tsKeycount, holdtime, livetime)
        End Function

        Public Function tsKeyCount(ByVal host As String, ByVal port As Int32, _
                                   ByRef count As UInt64, _
                                   Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                   Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tsKeyCount(Nothing, host, port, count, holdtime, livetime)
        End Function

        Public Function tryTsKeyCount(ByRef talk As tcpTalk, ByVal host As String, ByVal port As Int32, _
                                      ByRef count As UInt64, _
                                      Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                      Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                      Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return trykeycountImpl(talk, host, port, count, AddressOf tsKeyCount, retrytimes, holdtime, livetime)
        End Function

        Public Function tryTsKeyCount(ByVal host As String, ByVal port As Int32, _
                                      ByRef count As UInt64, _
                                      Optional ByVal retrytimes As UInt64 = defaultRetryTimes, _
                                      Optional ByVal holdtime As Int64 = defaultHoldTime, _
                                      Optional ByVal livetime As Int64 = defaultLiveTime) As returnValue
            Return tryTsKeyCount(Nothing, host, port, count, retrytimes, holdtime, livetime)
        End Function
    End Module
End Namespace
